﻿using System.Collections.Generic;
using System.ComponentModel;
using SubSonic;

namespace CommonLibrary
{
	/// <summary>
	/// Base Business Layer
	/// </summary>
	/// <typeparam name="T">The entity type for this BL</typeparam>
	/// <typeparam name="C">The collection of entity types</typeparam>
	[DataObject(true)]
	public abstract class BusinessBase<T, C>
		where T : RepositoryRecord<T>, IRecordBase, new()
		where C : List<T>, new()
	{
		#region Private Fields

		protected C _all;

		#endregion

		#region Protected Properties

		protected TableSchema.Table Table { get; set; }

		#endregion

		#region Protected Methods

		/// <summary>
		/// Return a strongly typed collection of records. Does not need to be of the same type as the 
		/// class T & C
		/// </summary>
		/// <typeparam name="L">The collection type</typeparam>
		/// <typeparam name="E">The entity type</typeparam>
		/// <param name="query">The query to execute</param>
		/// <returns></returns>
		protected L GetCollection<L, E>(SqlQuery query)
			where E : RepositoryRecord<E>, IRecordBase, new()
			where L : List<E>, new()
		{
			L retVal = new L();
			List<E> list = query.ExecuteTypedList<E>();
			if (list != null && list.Count > 0)
			{
				retVal.AddRange(list);
			}
			return retVal;
		}

		/// <summary>
		/// Return a collection of data entities based on the query passed in
		/// </summary>
		/// <param name="query"></param>
		/// <returns></returns>
		protected C GetCollection(SqlQuery query)
		{
			return GetCollection<C, T>(query);
		}

		#endregion

		#region Constructor

		public BusinessBase(TableSchema.Table table)
		{
			Table = table;
		}

		#endregion

		#region Public Properties

		/// <summary>
		/// Return all the items
		/// </summary>
		public virtual C All
		{
			get
			{
				if (_all == null)
				{
					_all = GetAll();
				}
				return _all;
			}
		}

		#endregion

		#region Public Methods

		[DataObjectMethod(DataObjectMethodType.Select, true)]
		public virtual C GetAll()
		{
			_all = GetCollection(new Select().From(Table));
			return _all;
		}

		#endregion
	}
}
